#include "remindersettings.h"

#include <QSettings>
#include <QFileDialog>
#include <QMessageBox>
#include <QDir>
#include <QProcess>
#include <QPushButton>

#ifdef Q_OS_WIN
    #include <windows.h>
    #include <shellapi.h>
#endif

#include <QtDebug>

ReminderSettings::ReminderSettings(QWidget *parent, Qt::WindowFlags f)
    : QDialog(parent, f),
      ui(new Ui::ReminderSettings)
{
    ui->setupUi(this);
    this->loadSettings();

#ifdef Q_OS_WIN
    QPushButton *button = ui->buttonBox->button( QDialogButtonBox::Ok );
    button->setIcon(QIcon(":/Icons/icons/UacIcon.png"));
#endif
}

ReminderSettings::~ReminderSettings()
{
    if(ui) delete(ui);
}

void ReminderSettings::accept()
{
    this->saveSettings();
    QDialog::accept();
}

void ReminderSettings::loadSettings()
{
    QSettings registry(QSettings::NativeFormat, QSettings::SystemScope, "Venelin Georgiev", "MindReminder");
    QDir appdir(registry.value("IniPath", QDir::homePath()).toString());
    //QDir appdir = qApp->applicationDirPath();
    QSettings settings(appdir.filePath("MindReminder.ini"), QSettings::IniFormat);
    settings.beginGroup("Settings");
    ui->minimized_checkBox->setChecked(settings.value("RunMinimized", true).toBool());
    ui->secconds_use_checkBox->setChecked(settings.value("UseSecconds", false).toBool());
    ui->check_missed_checkBox->setChecked(settings.value("CheckMissed", false).toBool());
    settings.endGroup();
    QSettings startup("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    //QSettings startup("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::IniFormat);
    ui->startup_checkBox->setChecked(startup.value("mindreminder").toString() == QDir::toNativeSeparators(qApp->applicationFilePath()));
    ui->ini_lineEdit->setText(appdir.absolutePath());
}

void ReminderSettings::saveSettings()
{
    QDir appdir(ui->ini_lineEdit->text());
    //QDir appdir = qApp->applicationDirPath();
    QSettings settings(appdir.filePath("MindReminder.ini"), QSettings::IniFormat);
    settings.beginGroup("Settings");
    settings.setValue("AutoStartup", ui->startup_checkBox->isChecked());
    settings.setValue("RunMinimized", ui->minimized_checkBox->isChecked());
    settings.setValue("UseSecconds", ui->secconds_use_checkBox->isChecked());
    settings.setValue("CheckMissed", ui->check_missed_checkBox->isChecked());
    settings.endGroup();

    QDir prog = qApp->applicationDirPath();
    QString program = prog.filePath("uacworker.exe");

    QStringList arguments;

    arguments << "-sys=\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\"" << "-syskey=mindreminder";
    if(ui->startup_checkBox->isChecked()) arguments << QString("-sysvalue=\"%1\"").arg(QDir::toNativeSeparators(qApp->applicationFilePath()));
    else arguments << "-remove";
    arguments << "-rorg=\"Venelin Georgiev\"" << "-rapp=MindReminder";
    arguments << "-rk0=IniPath" << QString("-rv0=\"%1\"").arg(ui->ini_lineEdit->text());

#ifdef Q_OS_WIN
    int result = (int)::ShellExecuteA(0, "open", program.toUtf8().constData(), arguments.join(" ").toUtf8().constData(), 0,  SW_HIDE/*SW_SHOWNORMAL*/);
    if (SE_ERR_ACCESSDENIED == result)
    {
        // Requesting elevation
        result = (int)::ShellExecuteA(0, "runas", program.toUtf8().constData(), arguments.join(" ").toUtf8().constData(), 0, SW_HIDE /* SW_SHOWNORMAL*/);
    }
    if (result <= 32)
    {
        // error handling
    }
#else
    if (!QProcess::startDetached(program))
    {
        // error handling
    }
#endif

         /*int res = myProcess->execute(program, arguments);
         qDebug() << "UACWorker system program registry result: " << res;
         */

         //QSettings registry(QSettings::NativeFormat, QSettings::SystemScope, "Venelin Georgiev", "MindReminder");
         //registry.setValue("IniPath", ui->ini_lineEdit->text());

    //QSettings startup("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::IniFormat); //UAC restrictions
    //QSettings startup("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    //if(ui->startup_checkBox->isChecked()) startup.setValue("mindreminder", QDir::toNativeSeparators(qApp->applicationFilePath()));
    //else startup.remove("mindreminder");
    qApp->setProperty("use_secconds", ui->secconds_use_checkBox->isChecked());

    emit this->settingsChanged();
}

void ReminderSettings::on_ini_toolButton_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                     ui->ini_lineEdit->text(),
                                                     QFileDialog::ShowDirsOnly
                                                     | QFileDialog::DontResolveSymlinks);

    if(!dir.isEmpty() && QDir(dir) != QDir(ui->ini_lineEdit->text())){
        QMessageBox msgBox;
        msgBox.setWindowTitle("Mind Reminder");
        msgBox.setText(tr("Change in the location of the settings file."));
        msgBox.setInformativeText(tr("Do you want to keep the current settings file?\n"
                                     "This action will overwrite the configuration file\n"
                                     "in the selected directory (if it exists)!"
                                     ));
        msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
        msgBox.setDefaultButton(QMessageBox::No);
        int ret = msgBox.exec();

        QSettings registry(QSettings::NativeFormat, QSettings::SystemScope, "Venelin Georgiev", "MindReminder");
        QDir appdir(registry.value("IniPath", QDir::homePath()).toString());
        QDir new_appdir(dir);
        if(ret == QMessageBox::Yes){
            QFile* exists_file = new QFile(new_appdir.filePath("MindReminder.ini"));
            if(exists_file->exists()){
            //qDebug() << "Settings file exists";
                QFile* exists_bac_file = new QFile(new_appdir.filePath("MindReminder.ini.bac"));
                if(exists_bac_file->exists()){
                    //qDebug() << "Settings backup file exists";
                    if(!exists_bac_file->remove()){
                        if(exists_bac_file->error()!=0){
                            QMessageBox::critical ( this, tr("Error"), tr("Can't remove exists backup file. Reason:\n%1").arg(exists_bac_file->errorString()));
                            delete exists_file;
                            delete exists_bac_file;
                            return;
                        }
                    }
                }
                //else qDebug() << "Settings backup file not exists";
                if(!exists_file->copy(exists_bac_file->fileName())){
                    if(exists_file->error()!=0){
                        QMessageBox::warning( this, tr("Warning"), tr("Copy of settings file failed. Reason:\n%1").arg(exists_file->errorString()));
                    }
                }
                delete exists_bac_file;
                if(!exists_file->remove()){
                    if(exists_file->error()!=0){
                        QMessageBox::critical ( this, tr("Error"), tr("Can't remove exists settings file. Reason:\n%1").arg(exists_file->errorString()));
                        delete exists_file;
                        return;
                    }
                }
            }
            //else qDebug() << "Settings file not exists";
            QFile* settings = new QFile(appdir.filePath("MindReminder.ini"));
            if(settings->exists()){
                if(!settings->copy(exists_file->fileName())){
                    if(settings->error()!=0){
                        QMessageBox::critical ( this, tr("Error"), tr("Copy of settings file failed. Reason:\n%1").arg(settings->errorString()));
                        delete settings;
                        return;
                    }
                    else delete settings;
                }
            }
            else{

            }
            QFileInfo finfo(*exists_file);
            if(exists_file->exists()){
                if(!finfo.isWritable()){
                    QMessageBox::critical ( this, tr("Error"), tr("You do not have write permissions in this directory"));
                    delete exists_file;
                    return;
                }
            }
            delete exists_file;
        }
        ui->ini_lineEdit->setText(dir);
    }
}
